home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Delphi Informant Complete 1995 - 2000
/
Delphi Informant Complete 1995 to 2000.iso
/
Delphi Informant Magazine Complete Works SOURCE CODE 1998.rar
/
1998
/
Sep
/
di9809rs
/
LINEARF.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1998-03-03
|
5KB
|
187 lines
unit LinearF;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;
type
TLinearForm = class(TForm)
CmdGo: TButton;
DrawBox: TPaintBox;
procedure FormResize(Sender: TObject);
procedure DrawBoxPaint(Sender: TObject);
procedure CmdGoClick(Sender: TObject);
procedure DrawBoxMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
procedure DrawPoint(i : Integer);
public
{ Public declarations }
end;
procedure LeastSquares(PtX, PtY : array of Integer;
NumPts, max_x, max_y : Integer;
var x1, y1, x2, y2 : Integer);
var
LinearForm: TLinearForm;
implementation
{$R *.DFM}
var
NumPts, X1, Y1, X2, Y2 : Integer;
PtX, PtY : array [0..100] of Integer;
first_point : Boolean;
// Make DrawBox as big as possible.
procedure TLinearForm.FormResize(Sender: TObject);
const
GAP = 3;
var
hgt : Integer;
begin
if (WindowState = wsMinimized) then Exit;
hgt := ClientHeight - CmdGo.Height - 3 * GAP;
if (hgt < 10) then hgt := 10;
DrawBox.Left := GAP;
DrawBox.Top := GAP;
DrawBox.Width := ClientWidth - 2 * GAP;
DrawBox.Height := hgt;
CmdGo.Left := (ClientWidth - CmdGo.Width) Div 2;
CmdGo.Top := hgt + 2 * GAP;
DrawBox.Canvas.Refresh;
end;
// Draw the points and the linear least squares line.
procedure TLinearForm.DrawBoxPaint(Sender: TObject);
const
GAP = 2;
var
i : Integer;
begin
for i := 1 to NumPts do
begin
DrawPoint(i);
end;
// If we have a least squares line, draw it.
if (X1 >= 0) then
begin
DrawBox.Canvas.MoveTo(X1, Y1);
DrawBox.Canvas.LineTo(X2, Y2);
end;
end;
// Draw the line and reset the points.
procedure TLinearForm.CmdGoClick(Sender: TObject);
begin
// Calculate the least squares line.
LeastSquares(PtX, PtY, NumPts,
DrawBox.ClientWidth - 1, DrawBox.ClientHeight - 1,
X1, Y1, X2, Y2);
// Draw the line.
first_point := True;
DrawBox.Invalidate;
CmdGo.Enabled := False;
end;
// Draw a small box for the point.
procedure TLinearForm.DrawPoint(i : Integer);
const
GAP = 2;
begin
DrawBox.Canvas.Rectangle(
PtX[i] - GAP, PtY[i] - GAP,
PtX[i] + GAP, PtY[i] + GAP);
end;
// Save this point.
procedure TLinearForm.DrawBoxMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
// If this is the first point, reset everything.
if (first_point) then
begin
NumPts := 0; // We have no points.
X1 := -1; // We have no least squares line.
DrawBox.Invalidate; // Erase everything.
first_point := False; // We have our first point.
end;
if (NumPts < 100) then NumPts := NumPts + 1;
PtX[NumPts] := X;
PtY[NumPts] := Y;
// Plot the point.
DrawPoint(NumPts);
// Enable the command button if
// there are at least two points.
CmdGo.Enabled := (NumPts > 1);
end;
procedure TLinearForm.FormCreate(Sender: TObject);
begin
// Indicate we need to get the first point.
first_point := True;
// Indicate we do not have a least squares line yet.
X1 := -1;
end;
// Find the least squares line.
procedure LeastSquares(PtX, PtY : array of Integer;
NumPts, max_x, max_y : Integer;
var x1, y1, x2, y2 : Integer);
var
S1, Sx, Sy, Sxx, Sxy, m, b : Single;
i : Integer;
begin
// Calculate the least squares sums.
S1 := 0;
Sx := 0;
Sy := 0;
Sxx := 0;
Sxy := 0;
for i := 1 to NumPts do
begin
S1 := S1 + 1;
Sx := Sx + PtX[i];
Sy := Sy + PtY[i];
Sxx := Sxx + PtX[i] * PtX[i];
Sxy := Sxy + PtX[i] * PtY[i];
end;
// Make sure the line isn't vertical.
if ((S1 * Sxx - Sx * Sx) = 0) then
begin
x1 := PtX[1];
x2 := x1;
y1 := 0;
y2 := max_y;
end else
begin
// Calculate m and b.
m := (S1 * Sxy - Sx * Sy) / (S1 * Sxx - Sx * Sx);
b := (Sxx * Sy - Sx * Sxy) / (S1 * Sxx - Sx * Sx);
// Calculate the line's end points.
x1 := 0;
y1 := Round(m * x1 + b);
x2 := max_x;
y2 := Round(m * x2 + b);
end;
end;
end.